扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:刘涛 来源:天极开发 2007年10月16日
关键字:
// XTreeCtrl.h : header file #if !defined(AFX_XTREECTRL_H__3EF12526_EF66_4FD9_A572_59476441D79A__INCLUDED_) #define AFX_XTREECTRL_H__3EF12526_EF66_4FD9_A572_59476441D79A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CXTreeCtrl : public CTreeCtrl { // Construction public: CXTreeCtrl(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CXTreeCtrl) //}}AFX_VIRTUAL // Implementation public: virtual ~CXTreeCtrl(); // Generated message map functions protected: UINT m_TimerTicks; //处理滚动的定时器所经过的时间 UINT m_nScrollTimerID; //处理滚动的定时器 CPoint m_HoverPoint; //鼠标位置 UINT m_nHoverTimerID; //鼠标敏感定时器 DWORD m_dwDragStart; //按下鼠标左键那一刻的时间 BOOL m_bDragging; //标识是否正在拖动过程中 CImageList* m_pDragImage; //拖动时显示的图象列表 HTREEITEM m_hItemDragS; //被拖动的标签 HTREEITEM m_hItemDragD; //接受拖动的标签 //{{AFX_MSG(CXTreeCtrl) afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnTimer(UINT nIDEvent); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: HTREEITEM CopyBranch(HTREEITEM htiBranch,HTREEITEM htiNewParent,HTREEITEM htiAfter); HTREEITEM CopyItem(HTREEITEM hItem,HTREEITEM htiNewParent,HTREEITEM htiAfter); }; #endif //////////////////////////////////////////////////////////// CXTreeCtrl #include "stdafx.h" #include "DragTree.h" #include "XTreeCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define DRAG_DELAY 60 CXTreeCtrl::CXTreeCtrl() { m_bDragging = false; } CXTreeCtrl::~CXTreeCtrl() {} BEGIN_MESSAGE_MAP(CXTreeCtrl, CTreeCtrl) //{{AFX_MSG_MAP(CXTreeCtrl) ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag) ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_WM_LBUTTONDOWN() ON_WM_TIMER() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CXTreeCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; *pResult = 0; //如果是无意拖曳,则放弃操作 if( (GetTickCount() - m_dwDragStart) < DRAG_DELAY ) return; m_hItemDragS = pNMTreeView->itemNew.hItem; m_hItemDragD = NULL; //得到用于拖动时显示的图象列表 m_pDragImage = CreateDragImage( m_hItemDragS ); if( !m_pDragImage ) return; m_bDragging = true; m_pDragImage->BeginDrag ( 0,CPoint(8,8) ); CPoint pt = pNMTreeView->ptDrag; ClientToScreen( &pt ); m_pDragImage->DragEnter ( this,pt ); //"this"将拖曳动作限制在该窗口 SetCapture(); m_nScrollTimerID = SetTimer( 2,40,NULL ); } void CXTreeCtrl::OnMouseMove(UINT nFlags, CPoint point) { HTREEITEM hItem; UINT flags; //检测鼠标敏感定时器是否存在,如果存在则删除,删除后再定时 if( m_nHoverTimerID ) { KillTimer( m_nHoverTimerID ); m_nHoverTimerID = 0; } m_nHoverTimerID = SetTimer( 1,800,NULL ); //定时为 0.8 秒则自动展开 m_HoverPoint = point; if( m_bDragging ) { CPoint pt = point; CImageList::DragMove( pt ); //鼠标经过时高亮显示 CImageList::DragShowNolock( false ); //避免鼠标经过时留下难看的痕迹 if( (hItem = HitTest(point,&flags)) != NULL ) { SelectDropTarget( hItem ); m_hItemDragD = hItem; } CImageList::DragShowNolock( true ); //当条目被拖曳到左边缘时,将条目放在根下 CRect rect; GetClientRect( &rect ); if( point.x < rect.left + 20 ) m_hItemDragD = NULL; } CTreeCtrl::OnMouseMove(nFlags, point); } void CXTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point) { CTreeCtrl::OnLButtonUp(nFlags, point); if( m_bDragging ) { m_bDragging = FALSE; CImageList::DragLeave( this ); CImageList::EndDrag(); ReleaseCapture(); delete m_pDragImage; SelectDropTarget( NULL ); if( m_hItemDragS == m_hItemDragD ) { KillTimer( m_nScrollTimerID ); return; } Expand( m_hItemDragD,TVE_EXPAND ); HTREEITEM htiParent = m_hItemDragD; while( (htiParent = GetParentItem(htiParent)) != NULL ) { if( htiParent == m_hItemDragS ) { HTREEITEM htiNewTemp = CopyBranch( m_hItemDragS,NULL,TVI_LAST ); HTREEITEM htiNew = CopyBranch( htiNewTemp,m_hItemDragD,TVI_LAST ); DeleteItem( htiNewTemp ); SelectItem( htiNew ); KillTimer( m_nScrollTimerID ); return; } } HTREEITEM htiNew = CopyBranch( m_hItemDragS,m_hItemDragD,TVI_LAST ); DeleteItem( m_hItemDragS ); SelectItem( htiNew ); KillTimer( m_nScrollTimerID ); } } HTREEITEM CXTreeCtrl::CopyItem(HTREEITEM hItem, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝条目 { TV_INSERTSTRUCT tvstruct; HTREEITEM hNewItem; CString sText; //得到源条目的信息 tvstruct.item.hItem = hItem; tvstruct.item.mask=TVIF_CHILDREN|TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE; GetItem( &tvstruct.item ); sText = GetItemText( hItem ); tvstruct.item.cchTextMax = sText.GetLength (); tvstruct.item.pszText = sText.LockBuffer (); //将条目插入到合适的位置 tvstruct.hParent = htiNewParent; tvstruct.hInsertAfter = htiAfter; tvstruct.item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT; hNewItem = InsertItem( &tvstruct ); sText.ReleaseBuffer (); //限制拷贝条目数据和条目状态 SetItemData( hNewItem,GetItemData(hItem) ); SetItemState( hNewItem,GetItemState(hItem,TVIS_STATEIMAGEMASK),TVIS_STATEIMAGEMASK); return hNewItem; } HTREEITEM CXTreeCtrl::CopyBranch(HTREEITEM htiBranch, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝分支 { HTREEITEM hChild; HTREEITEM hNewItem = CopyItem( htiBranch,htiNewParent,htiAfter ); hChild = GetChildItem( htiBranch ); while( hChild != NULL ) { CopyBranch( hChild,hNewItem,htiAfter ); hChild = GetNextSiblingItem( hChild ); } return hNewItem; } void CXTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point) //处理无意拖曳 { m_dwDragStart = GetTickCount(); CTreeCtrl::OnLButtonDown(nFlags, point); } void CXTreeCtrl::OnTimer(UINT nIDEvent) { //鼠标敏感节点 if( nIDEvent == m_nHoverTimerID ) { KillTimer( m_nHoverTimerID ); m_nHoverTimerID = 0; HTREEITEM trItem = 0; UINT uFlag = 0; trItem = HitTest( m_HoverPoint,&uFlag ); if( trItem && m_bDragging ) { SelectItem( trItem ); Expand( trItem,TVE_EXPAND ); } } //处理拖曳过程中的滚动问题 else if( nIDEvent == m_nScrollTimerID ) { m_TimerTicks++; CPoint pt; GetCursorPos( &pt ); CRect rect; GetClientRect( &rect ); ClientToScreen( &rect ); HTREEITEM hItem = GetFirstVisibleItem(); if( pt.y < rect.top +10 ) { //向上滚动 int slowscroll = 6 - (rect.top + 10 - pt.y )/20; if( 0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)) ) { CImageList::DragShowNolock ( false ); SendMessage( WM_VSCROLL,SB_LINEUP ); SelectDropTarget( hItem ); m_hItemDragD = hItem; CImageList::DragShowNolock ( true ); } } else if( pt.y > rect.bottom - 10 ) { //向下滚动 int slowscroll = 6 - (pt.y - rect.bottom + 10)/20; if( 0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)) ) { CImageList::DragShowNolock ( false ); SendMessage( WM_VSCROLL,SB_LINEDOWN ); int nCount = GetVisibleCount(); for( int i=0 ; i<nCount-1 ; i++ ) hItem = GetNextVisibleItem( hItem ); if( hItem ) SelectDropTarget( hItem ); m_hItemDragD = hItem; CImageList::DragShowNolock ( true ); } } } else CTreeCtrl::OnTimer(nIDEvent); } //////////////////////////////////////////////////////////// BOOL CDragTreeDlg::OnInitDialog() { CDialog::OnInitDialog(); …………………….//此处代码省略 // TODO: Add extra initialization here m_image.Create ( IDB_TREEIMAGE,16,1,RGB(255,255,255) ); m_wndTree.SetImageList ( &m_image,TVSIL_NORMAL ); HTREEITEM hti1 = m_wndTree.InsertItem ( _T("唐詩"),0,1 ); HTREEITEM hti2 = m_wndTree.InsertItem ( _T("宋詞"),0,1 ); HTREEITEM hti3 = m_wndTree.InsertItem ( _T("元曲"),0,1 ); HTREEITEM hti4 = m_wndTree.InsertItem ( _T("李白"),0,1,hti1 ); m_wndTree.InsertItem ( _T("靜夜思(床前明月光)"),0,1,hti4 ); m_wndTree.InsertItem ( _T("將進酒(君不見黃河之水天上來)"),0,1,hti4 ); m_wndTree.InsertItem ( _T("望廬山瀑布(日照香爐生紫煙)"),0,1,hti4 ); m_wndTree.InsertItem ( _T("蜀道難(噫吁戲,危乎高哉)"),0,1,hti4 ); HTREEITEM hti5 = m_wndTree.InsertItem ( _T("杜甫"),0,1,hti1 ); m_wndTree.InsertItem ( _T("蜀相(丞相祠堂何處尋)"),0,1,hti5 ); m_wndTree.InsertItem ( _T("春望(國破山河在)"),0,1,hti5 ); m_wndTree.InsertItem ( _T("茅屋為秋風所破歌(八月秋高風怒號)"),0,1,hti5 ); HTREEITEM hti6 = m_wndTree.InsertItem ( _T("白居易"),0,1,hti1 ); m_wndTree.InsertItem ( _T("長恨歌(漢皇重色思傾國)"),0,1,hti6 ); m_wndTree.InsertItem ( _T("琵琶行並序(潯陽江頭夜送客)"),0,1,hti6 ); m_wndTree.InsertItem ( _T("李清照"),0,1,hti2 ); m_wndTree.InsertItem ( _T("柳永"),0,1,hti2 ); return TRUE; // return TRUE unless you set the focus to a control } |
濠电姷鏁告慨鐑姐€傛禒瀣劦妞ゆ巻鍋撻柛鐔锋健閸┾偓妞ゆ巻鍋撶紓宥咃躬楠炲啫螣鐠囪尙绐為梺褰掑亰閸撴盯鎮惧ú顏呪拺闂傚牊鍗曢崼銉ョ柧婵犲﹤瀚崣蹇旂節婵犲倻澧涢柛瀣ㄥ妽閵囧嫰寮介妸褋鈧帡鏌熼挊澶婃殻闁哄瞼鍠栭幃婊堝煛閸屾稓褰嬮柣搴ゎ潐濞叉ê鐣濈粙璺ㄦ殾闁割偅娲栭悡娑㈡煕鐏炲墽鐭嬫繛鍫熸倐濮婄粯鎷呯粵瀣異闂佹悶鍔嬮崡鍐茬暦閵忋倕鍐€妞ゆ劑鍎卞皬闂備焦瀵х粙鎴犫偓姘煎弮瀹曚即宕卞Ο闀愮盎闂侀潧鐗嗛幊搴㈡叏椤掆偓閳规垿鍩ラ崱妞剧凹濠电姰鍨洪敋閾荤偞淇婇妶鍛櫤闁稿鍊圭换娑㈠幢濡纰嶉柣搴㈣壘椤︾敻寮诲鍫闂佸憡鎸鹃崰搴敋閿濆鏁嗗〒姘功閻绻涢幘鏉戠劰闁稿鎹囬弻锝呪槈濞嗘劕纾抽梺鍝勬湰缁嬫垿鍩為幋锕€宸濇い鏇炴噺閳诲﹦绱撻崒娆戝妽妞ゃ劌鎳橀幆宀勫磼閻愰潧绁﹂柟鍏肩暘閸斿矂鎮為崹顐犱簻闁圭儤鍨甸鈺呮倵濮橆剦妲归柕鍥у瀵粙濡歌閸c儳绱撴担绛嬪殭婵☆偅绻堝濠氭偄绾拌鲸鏅i悷婊冪Ч閹﹢鎳犻鍌滐紲闁哄鐗勯崝搴g不閻愮儤鐓涢悘鐐跺Г閸犳﹢鏌℃担鐟板鐎规洜鍠栭、姗€鎮╅搹顐ら拻闂傚倷娴囧畷鍨叏閹惰姤鈷旂€广儱顦崹鍌炴煢濡尨绱氶柨婵嗩槸缁€瀣亜閺嶃劎鈽夋繛鍫熺矒濮婅櫣娑甸崨顔俱€愬銈庡亝濞茬喖宕洪埀顒併亜閹哄棗浜鹃梺鎸庢穿婵″洤危閹版澘绫嶉柛顐g箘椤撴椽姊虹紒妯哄鐎殿噮鍓欒灃闁告侗鍠氶崢鎼佹⒑閸撴彃浜介柛瀣閹﹢鏁冮崒娑氬幈闁诲函缍嗛崑鍡樻櫠椤掑倻纾奸柛灞剧☉缁椦囨煙閻熸澘顏柟鐓庢贡閹叉挳宕熼棃娑欐珡闂傚倸鍊风粈渚€骞栭銈傚亾濮樺崬鍘寸€规洖缍婇弻鍡楊吋閸涱垽绱遍柣搴$畭閸庨亶藝娴兼潙纾跨€广儱顦伴悡鏇㈡煛閸ャ儱濡煎褜鍨伴湁闁绘ǹ绉鍫熺畳闂備焦瀵х换鍌毼涘Δ鍛厺闁哄洢鍨洪悡鍐喐濠婂牆绀堟慨妯挎硾閽冪喖鏌曟繛褍瀚烽崑銊╂⒑缂佹ê濮囨い鏇ㄥ弮閸┿垽寮撮姀鈥斥偓鐢告煥濠靛棗鈧懓鈻嶉崶銊d簻闊洦绋愰幉楣冩煛鐏炵偓绀嬬€规洟浜堕、姗€鎮㈡總澶夌处